package com.csc.controller;

import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;

import com.csc.bean.NewMember;
import com.csc.domain.SystemAccount;
import com.csc.domain.SystemTimeUsed;
import com.csc.domain.TransactionHistory;
import com.csc.service.LoginService;
import com.csc.service.SystemAccountService;
import com.csc.service.SystemRequestService;
import com.csc.service.SystemTimeUsedService;
import com.csc.service.SystemTransactionHistoryService;

import constants.Constant;

@Controller
@SessionAttributes({ "user", "roleuser" })
public class LoginController {
	@Autowired
	LoginService loginService;

	@Autowired
	SystemTimeUsedService sysTimeSer;

	@Autowired
	SystemAccountService sysAccSer;

	@Autowired
	SystemTransactionHistoryService transHistorySer;

	@Autowired
	SystemRequestService requestService;

	@Autowired
	private MessageSource messageSource;

	private Logger logger = Logger.getLogger(LoginController.class);

	String temp = "";

	/**
	 * @author Nguyen Vu Hung START SECURITY
	 * 
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String doLogin() {
		return "login";
	}

	@RequestMapping(value = "/denied", method = RequestMethod.GET)
	public String doDeny() {
		logger.info("Go to denied page!");
		return "404";
	}

	@RequestMapping(value = "/home", method = RequestMethod.GET)
	public String doHome(HttpServletRequest request, Model model) {
		logger.info("Go Home!");
		String url = "";
		// Get username - add session user
		User user = (User) SecurityContextHolder.getContext()
				.getAuthentication().getPrincipal();
		String username = user.getUsername();

		// Set temp
		temp = username;

		model.addAttribute("user", username);
		// Get role - add session rolesuser
		Collection<GrantedAuthority> authorities = user.getAuthorities();

		// Redirect
		SystemAccount sysAccount = sysAccSer.getAccountByLoginId(username);
		if (sysAccount.getSystemStatus().getStatusId() == Constant.STATUS_ID_PREACTIVE) {
			model.addAttribute("username", username);
			url = "changepassword";
		} else {
			// Add action Login to SystemTimeUsed
			Date date = new Date();
			SimpleDateFormat dateFormat = new SimpleDateFormat(
					Constant.SIMPLE_DATE_FORMAT);
			String timeAction = dateFormat.format(date);
			SystemTimeUsed sysTime = new SystemTimeUsed(timeAction,
					Constant.ACTION_LOGIN);
			sysTime.setSysAccount(sysAccount);
			if (sysTimeSer.addSystemTimeUsed(sysTime)) {
				// Count user online
				loginService.addOnline(username);
				logger.info("Counter: " + loginService.getCurrentOnline());

				// Add session and redirect
				if (authorities.toString().contains("ROLE_ADMIN")) {
					model.addAttribute("roleuser", "admin");
					url = "forward:/adminmanager.html";
				} else {
					model.addAttribute("roleuser", "user");
					url = "user/manager";
				}
			}
		}
		return url;
	}
	// END SECURITY

	@RequestMapping(value = "/logout.html", method = RequestMethod.GET)
	public String doLogoutSuccess(SessionStatus session) {
		logger.info("Go to logout success!!!");
		SystemAccount sysAccount = sysAccSer.getAccountByLoginId(temp);
		// Add action Login to SystemTimeUsed
		Date date = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				Constant.SIMPLE_DATE_FORMAT);
		String timeAction = dateFormat.format(date);
		SystemTimeUsed sysTime = new SystemTimeUsed(timeAction,
				Constant.ACTION_LOGOUT);
		sysTime.setSysAccount(sysAccount);
		sysTimeSer.addSystemTimeUsed(sysTime);
		// Remove user online
		loginService.removeOnline(temp);
		session.setComplete();
		temp = "";
		logger.info("Counter: " + loginService.getCurrentOnline());
		return "login";
	}


	// Nguyen Vu Hung - i18n
	@RequestMapping(value = "/language", method = RequestMethod.GET)
	public String doChangeLanguage(HttpServletRequest request, Model model,
			@ModelAttribute("roleuser") String role) {
		if (null != role && role.equals(Constant.ROLE_ADMIN))
			return "admin/manager";
		return "user/manager";
	}
	
	
	@RequestMapping(value = "/usermanager", method = RequestMethod.GET)
	public String doUserManager() {
		return "user/manager";
	}

	@RequestMapping(value = "/admin", method = RequestMethod.GET)
	public String goBlogrequests(HttpServletRequest request) {
		return "admin/blogrequests";
	}

	@RequestMapping(value = "/settingAdmin")
	public String goAdminSettings(Model model,
			@ModelAttribute("user") String userName, HttpServletRequest request) {
		List<SystemAccount> listAccount = sysAccSer
				.getAccountsByUsername(userName);
		model.addAttribute("listAcc", listAccount);

		String message = "";
		if (request.getAttribute("message") == null) {
			message = "";
		} else {
			message = request.getAttribute("message").toString();

		}
		model.addAttribute("message", message);
		return "admin/settings";
	}

	@RequestMapping(value = "/newmember", method = RequestMethod.GET)
	public String goNewMembers(@ModelAttribute("user") String username,
			Model model) {
		SystemAccount sysAccount = sysAccSer.getAccountByLoginId(username);
		model.addAttribute("role", sysAccount.getSystemAccountType()
				.getTypeId());
		/* @author: Tran Son Hoang---Action:List new Users */
		logger.info("we are listing new User on admin page...");
		List<TransactionHistory> viewNewUsers = sysAccSer
				.getListAdminNewUsers();
		model.addAttribute("viewNewUsers", viewNewUsers);
		return "admin/newUser";
	}

	@RequestMapping(value = "/loadNewmember", method = RequestMethod.POST)
	public String goLoadNewMembers(@ModelAttribute("user") String username,
			Model model) {
		SystemAccount sysAccount = sysAccSer.getAccountByLoginId(username);
		model.addAttribute("role", sysAccount.getSystemAccountType()
				.getTypeId());
		/* @author: Tran Son Hoang---Action:List new Users */
		logger.info("we are listing new User on admin page...");
		List<TransactionHistory> viewNewUsers = sysAccSer
				.getListAdminNewUsers();
		model.addAttribute("viewNewUsers", viewNewUsers);
		return "admin/newUser";
	}

	@RequestMapping(value = "/newrequest", method = RequestMethod.GET)
	public String goNewRequests(HttpServletRequest request) {
		return "admin/newRequest";
	}

	@RequestMapping(value = "/listrequest", method = RequestMethod.GET)
	public String goListRequest(HttpServletRequest request) {
		return "admin/listusers";
	}

	/**
	 * @author Nguyen Vu Hung
	 * @param request
	 * @param model
	 * @return
	 */

	@RequestMapping(value = "/adminmanager", method = RequestMethod.GET)
	public String goAdminManagerGet(HttpServletRequest request, Model model) {
		return goAdminManagerPost(request, model);
	}

	// Nguyen Vu Hung - Admin Manager
	@RequestMapping(value = "/adminmanager", method = RequestMethod.POST)
	public String goAdminManagerPost(HttpServletRequest request, Model model) {
		// Count all users
		int numUsers = sysAccSer.getListAccountActive().size();
		model.addAttribute("numUsers", numUsers);

		// Count the number of each type user
		Map<String, Integer> mapNum = sysAccSer.countNumAccountSystem();
		model.addAttribute("allNum", mapNum);

		// Percent
		Map<String, Float> mapPercent = new HashMap<String, Float>();
		mapPercent.put("perUserAdmin", (float) sysAccSer
				.countNumAccountSystem().get("User Admin") / numUsers * 100);
		mapPercent.put("perUserSupport", (float) sysAccSer
				.countNumAccountSystem().get("User Support") / numUsers * 100);
		mapPercent.put("perAccAdmin", (float) sysAccSer.countNumAccountSystem()
				.get("Account Admin") / numUsers * 100);
		mapPercent.put("perAccSupport", (float) sysAccSer
				.countNumAccountSystem().get("Account Support")
				/ numUsers
				* 100);
		mapPercent
				.put("perReportSupport", (float) sysAccSer
						.countNumAccountSystem().get("Report Support")
						/ numUsers * 100);
		model.addAttribute("allPer", mapPercent);

		// Counter
		model.addAttribute("counter", loginService.getCurrentOnline());

		// Request
		model.addAttribute("numrequests", transHistorySer
				.getListTransactionRequestByAdminReport().size());

		return "admin/manager";
	}

	@RequestMapping(value = "/blogrequest", method = RequestMethod.GET)
	public String goAdminBlogRequest(HttpServletRequest request) {
		return "admin/blogrequests";
	}

	// /////////////////////////// End test

	/**
	 * @author Nguyen Vu Hung Logout then go to login page and remove session
	 *         "user"
	 */

	// Nguyen Vu Hung - Lock Screen
	@RequestMapping(value = "/lockscreen", method = RequestMethod.GET)
	public String goLockScreen(HttpServletRequest request) {
		request.getSession().setAttribute("pervious_page",
				request.getHeader("Referer"));
		request.getSession().setAttribute("isLockscreen", "true");
		return "lockscreen";
	}

	// Nguyen Vu Hung - Login again
	@RequestMapping(value = "/loginagain", method = RequestMethod.POST)
	public String doLoginAgain(HttpServletRequest request,
			@RequestParam("password") String password,
			@ModelAttribute("user") String username) {
		SystemAccount sysAccountCheck = sysAccSer.getAccountByLoginId(username);

		// Previous page
		HttpSession session = request.getSession();
		String pervious_page = (String) session.getAttribute("pervious_page");
		String url = pervious_page.substring(
				pervious_page.lastIndexOf('/') + 1, pervious_page.length());

		// Check password and redirect
		if (BCrypt.checkpw(password, sysAccountCheck.getAccountPassword())) {
			session.removeAttribute("pervious_page");
			session.removeAttribute("isLockscreen");
			return "redirect:/" + url;
		}
		return "lockscreen";
	}

	
	 // Nguyen Vu Hung - Admin: Count new users
	 
	  @RequestMapping(value = "/countnewuserjson", method = RequestMethod.GET)
	  public @ResponseBody int countAdminNewUser(HttpServletRequest request) {
	  return loginService.getListAccountNew().size(); }
	  
	  // Nguyen Vu Hung - Admin: Count new request
	  
	  @RequestMapping(value = "/countnewrequestjson", method =
	  RequestMethod.GET) public @ResponseBody int
	  countAdminNewRequest(HttpServletRequest request) { return
	  requestService.getNewRequests().size(); }
	 
	/**
	 * @author Truong Le Bao
	 */

	/* @author:Tran Son Hoang---Action go to register page */
	@RequestMapping(value = "/toAdminRegisterPage", method = RequestMethod.GET)
	public String goAdminRegisterPage(HttpServletRequest request, Model model,
			@ModelAttribute("user") String username) {
		logger.info("Admin is on process for registering new user...");
		SystemAccount sysAccount = sysAccSer.getAccountByLoginId(username);
		model.addAttribute("role", sysAccount.getSystemAccountType()
				.getTypeId());
		return "admin/register";
	}

	// @author:Tran Son Hoang ---Action: go to User/settings
	@RequestMapping(value = "/userSettings")
	public String goUserSettings(Model model,
			@ModelAttribute("user") String userName) {
		List<SystemAccount> currentAccount1 = sysAccSer
				.getAccountsByUsername(userName);
		SystemAccount acc = sysAccSer.getAccountByUsername(userName);
		
		model.addAttribute("currentAccount1", currentAccount1);
		model.addAttribute("currentAccount", acc);
		
		return "user/settings";
	}
}
